home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
editl.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-10
|
8KB
|
301 lines
// EDITL.CPP
#include <stdlib.h>
#include "editl.h"
#include "cursor.h"
EditLine::EditLine(loc pos, int l, int max_len, BORDERS b_type, int pat,
int insert)
: FormLine(b_type)
{
ins = insert;
string = strdup("");
xy = pos;
len = l - textX(area[border_type].origin.X
+ area[border_type].corner.X);
ret = pointTo = action_type = 0;
if(max_len == 0)
maxlen = 255;
else
maxlen = max_len;
pattern = pat;
}
/////////////////////////
void EditLine::bksp(int* cur_pos, int *vis_pos)
{
if(*cur_pos == strlen(string))
del(cur_pos, vis_pos);
left(cur_pos, vis_pos);
if(*cur_pos != strlen(string))
del(cur_pos, vis_pos);
}
/////////////////////////////
void EditLine::home(int* cur_pos, int* vis_pos)
{
*cur_pos = *vis_pos = 0;
redraw_string(xy, 0, 0);
}
//////////////////////
void EditLine::redraw_string(loc pos, int tmp, int start) // tmp - begin
{ // start - length
char* str = (char*)malloc(len + 2); // from begin
strncpy(str, string + tmp, len - start);
str[len - start/* + 1*/] = '\0';
FormLine::outtextxy(pos, len - start, str, pattern);
delete str;
}
////////////////////////
void EditLine::repose(rect new_coord)
{
xy = new_coord.origin;
len = new_coord.width() - 1;
}
////////////////////////
rect EditLine::bound()
{
return rect(screenLocLT(xy),
loc(screenXR(xy.X + len) + area[border_type].origin.X
+ area[border_type].corner.X,
screenYB(xy.Y) + pScreenSet->standart_height + 2
+ area[border_type].origin.Y + area[border_type].corner.Y));
}
/////////////////////////
void EditLine::put_string(char* str )
{
if(string)
delete string;
string = strdup(str);
}
////////////////////////
void EditLine::end(int* cur_pos, int* vis_pos)
{
*cur_pos = (strlen(string) < maxlen)
? strlen(string) : strlen(string) - 1;
*vis_pos = strlen(string) > len ?
strlen(string) - len : 0;
redraw_string(xy, *vis_pos);
}
/////////////////////////
void EditLine::hilite()
{
Carcase::show(PRESS_BORDER, rect(screenXL(xy.X),
screenYT(xy.Y),
screenXR(xy.X + len) + area[border_type].origin.X
+ area[border_type].corner.X,
screenYB(xy.Y) + pScreenSet->standart_height + 2
+ area[border_type].origin.Y + area[border_type].corner.Y));
}
///////////////////////
void EditLine::unhilite()
{
Carcase::show(border_type, rect(screenXL(xy.X),
screenYT(xy.Y),
screenXR(xy.X + len) + area[border_type].origin.X
+ area[border_type].corner.X,
screenYB(xy.Y) + pScreenSet->standart_height + 2
+ area[border_type].origin.Y + area[border_type].corner.Y));
}
//////////////////////
void EditLine::exe(int act)
{
Cursor curs;
mouseHideCursor();
hilite();
e.what = act ? KEYEVENT : NOEVENT;
global_i[0] = action_type;
switch(act)
{ // up, dn and so on may be added
case AC_CANCEL:
e.key = (isRet(RET_REMOVE))
? EVENT_ALT_F3 : EVENT_ESC;
break;
case AC_OK:
e.key = EVENT_F2;
break;
}
char* temp_str = string ? strdup(string) : strdup(""); // reserv copy
string = (char*)realloc(string, 256); // maximum, before exiting function
memset(string, '\0', 256); // it will be reallocated
strcpy(string, temp_str);
int cur_pos = 0; // current pos in string
int vis_pos = 0; // output begins from this position
settextjustify(LEFT_TEXT, BOTTOM_TEXT);
curs.set_cursor(screenXL(xy.X) + area[border_type].origin.X,
screenYT(xy.Y) + pScreenSet->standart_height
+ area[border_type].origin.Y);
curs.show_cursor();
while(1)
{
if(!act) // if act == 0 - we wait the event, else (f.e. CANCEL
// button pressed) - we process act, not event
{
mouseShowCursor();
get_event();
mouseHideCursor();
}
int x = getx(); int y = gety();
curs.set_cursor(screenXL(xy.X + cur_pos - vis_pos)
+ area[border_type].origin.X,
screenYT(xy.Y) + pScreenSet->standart_height
+ area[border_type].origin.Y);
curs.hide_cursor();
::moveto(x, y);
if(e.mouse1() || e.mouse2()) // mouse pressed
{
global_i[0] = 0;
break;
}
else
{
if(e.is_control()) // not visible char
switch(e.key)
{
case EVENT_F1: return;
case EVENT_LEFT: left(&cur_pos, &vis_pos); break;
case EVENT_RIGHT: right(&cur_pos, &vis_pos); break;
case EVENT_HOME: home(&cur_pos, &vis_pos); break;
case EVENT_END: end(&cur_pos, &vis_pos); break;
case EVENT_DEL: del(&cur_pos, &vis_pos); break;
case EVENT_BKSP: bksp(&cur_pos, &vis_pos); break;
case EVENT_INS: ins = !ins; break;
case EVENT_F10:
case EVENT_ESC: delete string; global_i[0] = 0;
string = strdup(temp_str); // don't change string
case EVENT_TAB:
case EVENT_F6:
case EVENT_F2:
case EVENT_ALT_F3:
case EVENT_ALT_F4:
case EVENT_ALT_TAB:
case EVENT_RETURN:
string =
(char*)realloc(string, strlen(string) + 2);
delete temp_str;
unhilite();
delete global[global_num];
if(global_num)
delete global[0];
global[global_num] = strdup(string);
if(global_num)
global[0] = strdup(string);
return;
}
else
if(e.is_char()) // visible char
{
outkey = e.key;
draw_char(&cur_pos, &vis_pos);
}
}
x = getx(); // new coords recalculation
y = gety();
curs.set_cursor(screenXL(xy.X + cur_pos - vis_pos)
+ area[border_type].origin.X,
screenYT(xy.Y) + pScreenSet->standart_height
+ area[border_type].origin.Y);
curs.show_cursor();
moveto(x, y);
}
// if mouse pressed outside - we keep the edited string
string = (char*)realloc(string, strlen(string) + 2);
delete temp_str;
unhilite();
delete global[global_num]; global[global_num] = strdup(string);
delete global[0]; global[0] = strdup(string);
return;
}
//////////////////////
void EditLine::draw_char(int* cur_pos, int* vis_pos)
{
int tmp;
int start = 0; // for length determination
int used = strlen(string);
if(used < maxlen || !ins)
{
insert(cur_pos);
if(*cur_pos - *vis_pos >= len) // shift all string 1 char left
tmp = ++(*vis_pos);
else
{
tmp = *cur_pos;
start = *cur_pos - *vis_pos;
}
redraw_string(loc(xy.X + start, xy.Y), tmp, start);
}
if((used < maxlen && *cur_pos < maxlen - 1 && ins)
|| (*cur_pos < maxlen - 1 && (!ins)))
(*cur_pos)++;
}
//////////////////////////////
void EditLine::del(int* cur_pos, int* vis_pos)
{
int i;
for(i = *cur_pos; i <= strlen(string); i++)
string[i] = string[i + 1];
redraw_string(xy, *vis_pos);
}
////////////////////////////////
void EditLine::left(int* cur_pos, int* vis_pos)
{
if(*cur_pos > 0)
(*cur_pos)--;
if(*cur_pos < *vis_pos)
{
(*vis_pos)--;
redraw_string(xy, *vis_pos);
}
}
///////////////////////////////
void EditLine::right(int* cur_pos, int* vis_pos)
{
if(*cur_pos < maxlen - 1 && *cur_pos < strlen(string))
(*cur_pos)++;
if(*cur_pos > *vis_pos + len && *cur_pos <= strlen(string))
{
(*vis_pos)++;
redraw_string(xy, *vis_pos);
}
}
////////////////////////////////
void EditLine::insert(int* cur_pos)
{
int l = strlen(string);
if(ins)
for(int i = l; i > *cur_pos; i--)
string[i] = string[i - 1];
string[*cur_pos] = outkey;
}
/////////////////////////////////
/*
void main()
{
if(!init_KNOW_HOW())
return;
setfillstyle(SOLID_FILL, pColorSet->colors.BAK_COLOR);
bar(0, 0, getmaxx(), getmaxy());
EditLine e(loc(10, 10), 40, 50, SHOW_BORDER, 17, 1);
e.put_string("Hello, WORLD !");
e.show();
e.exe();
close_KNOW_HOW();
closegraph();
}
*/